package com.cy.factory;

import com.cy.anno.Autowired;
import com.cy.anno.Component;
import com.cy.anno.Transactional;
import com.cy.utils.TransactionManager;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

@Component
public class ProxyFactory {

    @Autowired
    private TransactionManager transactionManager;

    /**
     * 使用JDK动态代理
     * @param obj
     * @return
     */
    public Object getJdkProxy(Object obj){
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Transactional annotation = method.getAnnotation(Transactional.class);
                        if (annotation == null){
                            System.out.println("没有使用JDK代理方法");
                            return method.invoke(obj, args);
                        }
                        else {
                            System.out.println("开始使用JDK代理方法");
                            Object object = null;

                            try {
                                transactionManager.beginTransaction();
                                //调用方法原始逻辑
                                object = method.invoke(obj, args);

                                transactionManager.commit();
                            }
                            catch (Exception e){
                                e.printStackTrace();
                                transactionManager.rollback();
                                throw e;
                            }

                            return object;
                        }
                    }
                });
    }

    /**
     * 使用Cglib动态代理
     * @param obj
     * @return
     */
    public Object getCglibProxy(Object obj){
        return Enhancer.create(obj.getClass(), new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                Transactional annotation = method.getAnnotation(Transactional.class);
                if (annotation == null){
                    System.out.println("没有使用Cglib代理方法");
                    return method.invoke(obj, objects);
                }
                else {
                    System.out.println("开始使用Cglib代理方法");
                    Object object = null;

                    try {
                        transactionManager.beginTransaction();
                        //调用方法原始逻辑
                        object = method.invoke(obj, objects);

                        transactionManager.commit();
                    }
                    catch (Exception e){
                        e.printStackTrace();
                        transactionManager.rollback();
                        throw e;
                    }

                    return object;
                }
            }
        });
    }

}
